package com.leyou.order.service.impl;

import com.leyou.common.constants.MQConstants;
import com.leyou.common.enums.ExceptionEnum;
import com.leyou.common.exceptions.LyException;
import com.leyou.common.threadlocals.UserHolder;
import com.leyou.common.utils.BeanHelper;
import com.leyou.common.utils.IdWorker;
import com.leyou.gateway.client.UserClient;
import com.leyou.item.client.ItemClient;
import com.leyou.item.dto.SkuDTO;
import com.leyou.order.dto.CartDTO;
import com.leyou.order.dto.OrderDTO;
import com.leyou.order.entity.Order;
import com.leyou.order.entity.OrderDetail;
import com.leyou.order.entity.OrderLogistics;
import com.leyou.order.enums.OrderStatusEnum;
import com.leyou.order.mapper.OrderDetailMapper;
import com.leyou.order.mapper.OrderLogisticsMapper;
import com.leyou.order.mapper.OrderMapper;
import com.leyou.order.service.IOrderService;
import com.leyou.order.vo.OrderDetailVO;
import com.leyou.order.vo.OrderLogisticsVO;
import com.leyou.order.vo.OrderVO;
import com.leyou.user.dto.AddressDTO;
import org.apache.commons.lang3.StringUtils;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 处理请求和响应的方法
 *
 * @version V1.0
 * @package com.leyou.order.service.impl
 * @description:
 * @author: pc
 * @date: 2019/7/13 20:06
 */
@Service("orderService")
public class OrderServiceImpl implements IOrderService {
    @Autowired
    private OrderMapper orderMapper;
    @Autowired
    private IdWorker idWorker;
    @Autowired
    private ItemClient itemClient;
    @Autowired
    private UserClient userClient;
    @Autowired
    private OrderLogisticsMapper orderLogisticsMapper;
    @Autowired
    private OrderDetailMapper orderDetailMapper;
    @Autowired
    private AmqpTemplate amqpTemplate;

    @Override
    @Transactional(rollbackFor = LyException.class)
    public Long creatOrder(OrderDTO orderDTO) {
        //1.创建订单
        Order order = new Order();
        //1.1雪花法创建订单编号
        long orderId = idWorker.nextId();
        //1.2添加订单编号
        order.setOrderId(orderId);
        //1.3订单金额相关
        //1.3.1查询商品skuId，去数据库查询jine
        List<CartDTO> carts = orderDTO.getCarts();
        //获得一个以商品ID及商品数量为键值对的map，方面确认金额总数
        Map<Long, Integer> numMap = carts.stream().collect(Collectors.toMap(CartDTO::getSkuId, CartDTO::getNum));
        //取出商品id的list集合
        List<Long> skuIdList = carts.stream().map(CartDTO::getSkuId).collect(Collectors.toList());
        //掉用方法查询sku
        List<SkuDTO> skuDTOS = itemClient.querySkuByIds(skuIdList);
        List<OrderDetail> orderDetailList = new ArrayList<>();
        long total = 0;
        for (SkuDTO sku : skuDTOS) {
            //从map中取出对应商品id的商品数量
            Integer num = numMap.get(sku.getId());
            //用数量计算出总金额
            total = sku.getPrice() * num;
            OrderDetail orderDetail = new OrderDetail();
            // 封装OrderDetail
            OrderDetail detail = new OrderDetail();
            detail.setTitle(sku.getTitle());
            detail.setSkuId(sku.getId());
            detail.setPrice(sku.getPrice());
            detail.setOwnSpec(sku.getOwnSpec());
            detail.setNum(num);
            detail.setImage(StringUtils.substringBefore(sku.getImages(), ","));
            detail.setOrderId(orderId);
            orderDetailList.add(detail);
        }
        //order赋值
        order.setTotalFee(total);
        order.setPaymentType(orderDTO.getPaymentType());
        order.setPostFee(0L);
        order.setActualFee(total + order.getPostFee());
        //1.4订单用户信息
        Long userId = UserHolder.getUser().getId();
        order.setUserId(userId);
        //1.5订单状态信息
        order.setStatus(OrderStatusEnum.INIT.value());
        //1.6写入order表
        int count = orderMapper.insertSelective(order);
        if (count != 1) {
            throw new LyException(ExceptionEnum.INSERT_OPERATION_FAIL);
        }

        // 2.新增订单详情
        count = orderMapper.insertList(orderDetailList);
        if (count != orderDetailList.size()) {
            throw new LyException(ExceptionEnum.INSERT_OPERATION_FAIL);
        }
        // 3.新增订单物流
        Long addressId = orderDTO.getAddressId();
        // 3.1.根据addressId查询物流信息
        AddressDTO address = userClient.queryAddressById(userId, addressId);
        // 3.2.封装OrderLogistics
        OrderLogistics orderLogistics = BeanHelper.copyProperties(address, OrderLogistics.class);
        orderLogistics.setOrderId(orderId);
        // 3.3.写入表
        count = orderLogisticsMapper.insertSelective(orderLogistics);
        if (count != 1) {
            throw new LyException(ExceptionEnum.INSERT_OPERATION_FAIL);
        }
        // 4.减库存
        try {
            itemClient.minusStock(numMap);
        } catch (Exception e) {
            throw new LyException(ExceptionEnum.STOCK_NOT_ENOUGH);
        }
        //发送消息给cart，删除该skuIdList中商品
        Map<String, Object> msg = new HashMap<>();
        msg.put("userId", userId.toString());
        msg.put("skuIdList", skuIdList);
        amqpTemplate.convertAndSend(MQConstants.Exchange.CART_EXCHANGE_NAME, MQConstants.RoutingKey.CART_DELETE_KEY, msg);

        return orderId;
    }

    @Override
    public OrderVO queryOrderByOrderId(Long orderId) {
        //通过订单编号查询订单
        Order order = orderMapper.selectByPrimaryKey(orderId);
        //判断订单是否存在
        if (order == null) {
            throw new LyException(ExceptionEnum.ORDER_NOT_FOUND);
        }
        //判断用户ID是否匹配
        //获取cookie中的userId
        Long id = UserHolder.getUser().getId();
        //获取订单中的userId
        Long userId = order.getUserId();
        if (!id.equals(userId)) {
            throw new LyException(ExceptionEnum.ORDER_NOT_FOUND);
        }
        //查询订单详情
        OrderDetail orderDetail = new OrderDetail();
        orderDetail.setOrderId(orderId);
        List<OrderDetail> orderDetailList = orderDetailMapper.select(orderDetail);
        if (CollectionUtils.isEmpty(orderDetailList)) {
            throw new LyException(ExceptionEnum.ORDER_NOT_FOUND);
        }
        //查询订单状态
        OrderLogistics orderLogistics = orderLogisticsMapper.selectByPrimaryKey(orderId);
        if (orderLogistics == null) {
            // 不存在
            throw new LyException(ExceptionEnum.ORDER_NOT_FOUND);
        }

        //封装数据
        OrderVO orderVO = BeanHelper.copyProperties(order, OrderVO.class);
        orderVO.setDetailList(BeanHelper.copyWithCollection(orderDetailList, OrderDetailVO.class));
        orderVO.setLogistics(BeanHelper.copyProperties(orderLogistics, OrderLogisticsVO.class));

        return orderVO;
    }
}
